package com.docmgmt.mvp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.docmgmt.mvp.dto.AddKbMemberRequest;
import com.docmgmt.mvp.dto.KbMemberVO;
import com.docmgmt.mvp.dto.UpdateKbMemberRequest;
import com.docmgmt.mvp.entity.*;
import com.docmgmt.mvp.exception.BusinessException;
import com.docmgmt.mvp.exception.ForbiddenException;
import com.docmgmt.mvp.mapper.*;
import com.docmgmt.mvp.service.MemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 知识库成员管理服务实现（KB-008）
 * <p>
 * 功能：
 * 1. 添加用户成员
 * 2. 添加部门授权（v3.0新增）
 * 3. 移除成员
 * 4. 更新成员权限
 * 5. 查询知识库所有成员
 * 6. 查询用户在知识库的权限
 * <p>
 * 权限级别：
 * - read: 只读（浏览、下载、AI问答）
 * - write: 编辑（read + 添加文件 + 删除自己的文件）
 * - manage: 管理（write + 删除任何文件 + 修改配置 + 管理成员）
 * - owner: 所有者（manage + 删除知识库）
 *
 * @author Dora
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberEntity> implements MemberService {

    private final MemberMapper memberMapper;
    private final KnowledgeBaseMapper knowledgeBaseMapper;
    private final UserMapper userMapper;
    private final DepartmentMapper departmentMapper;

    /**
     * 添加知识库成员（支持用户和部门两种类型）
     *
     * @param kbId      知识库ID
     * @param request   添加成员请求
     * @param operatorId 操作人ID
     * @return 成员信息VO
     */
    @Transactional
    public KbMemberVO addMember(Long kbId, AddKbMemberRequest request, Long operatorId) {
        log.info("添加知识库成员：kbId={}, memberType={}, memberId={}, permission={}",
                kbId, request.getMemberType(), request.getMemberId(), request.getPermissionType());

        // 1. 权限检查：仅owner可操作
        KnowledgeBaseEntity kb = knowledgeBaseMapper.selectById(kbId);
        if (kb == null) {
            throw new BusinessException("知识库不存在");
        }

        if (!kb.getOwnerId().equals(operatorId)) {
            throw new ForbiddenException("仅知识库owner可管理成员");
        }

        // 2. 验证成员存在性
        String memberName = validateAndGetMemberName(request.getMemberType(), request.getMemberId(), kb.getOwnerId());

        // 3. 检查是否已是成员（唯一性约束）
        LambdaQueryWrapper<MemberEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MemberEntity::getKbId, kbId)
                .eq(MemberEntity::getMemberType, request.getMemberType())
                .eq(MemberEntity::getMemberId, request.getMemberId());

        MemberEntity existingMember = memberMapper.selectOne(queryWrapper);
        if (existingMember != null) {
            String errorMsg = "user".equals(request.getMemberType()) ? "该用户已是知识库成员" : "该部门已被授权";
            throw new BusinessException(errorMsg);
        }

        // 4. 插入成员记录
        MemberEntity member = new MemberEntity();
        member.setKbId(kbId);
        member.setMemberType(request.getMemberType());
        member.setMemberId(request.getMemberId());
        member.setPermissionType(request.getPermissionType());
        member.setGrantedBy(operatorId);
        member.setGrantedAt(LocalDateTime.now());

        memberMapper.insert(member);

        log.info("知识库成员添加成功：id={}, kb_id={}, member_type={}, member_id={}",
                member.getId(), kbId, request.getMemberType(), request.getMemberId());

        // 5. 构建返回VO
        UserEntity operator = userMapper.selectById(operatorId);
        KbMemberVO vo = KbMemberVO.builder()
                .id(member.getId())
                .memberId(request.getMemberId())
                .memberType(request.getMemberType())
                .memberName(memberName)
                .permissionType(request.getPermissionType())
                .grantedBy(operatorId)
                .grantedByName(operator != null ? operator.getUsername() : "Unknown")
                .grantedAt(member.getGrantedAt())
                .build();

        // 6. 如果是部门，统计成员数
        if ("dept".equals(request.getMemberType())) {
            Long count = userMapper.selectCount(
                    new LambdaQueryWrapper<UserEntity>()
                            .eq(UserEntity::getDepartmentId, request.getMemberId())
                            .eq(UserEntity::getStatus, "active")
            );
            vo.setDepartmentMemberCount(count.intValue());
        }

        return vo;
    }

    /**
     * 移除知识库成员
     *
     * @param kbId       知识库ID
     * @param memberType 成员类型（user/dept）
     * @param memberId   成员ID
     * @param operatorId 操作人ID
     */
    @Transactional
    public void removeMember(Long kbId, String memberType, Long memberId, Long operatorId) {
        log.info("移除知识库成员：kbId={}, memberType={}, memberId={}", kbId, memberType, memberId);

        // 1. 权限检查：仅owner可操作
        KnowledgeBaseEntity kb = knowledgeBaseMapper.selectById(kbId);
        if (kb == null) {
            throw new BusinessException("知识库不存在");
        }

        if (!kb.getOwnerId().equals(operatorId)) {
            throw new ForbiddenException("仅知识库owner可管理成员");
        }

        // 2. 不能移除owner
        if ("user".equals(memberType) && memberId.equals(kb.getOwnerId())) {
            throw new BusinessException("不能移除知识库owner");
        }

        // 3. 删除成员记录
        LambdaQueryWrapper<MemberEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MemberEntity::getKbId, kbId)
                .eq(MemberEntity::getMemberType, memberType)
                .eq(MemberEntity::getMemberId, memberId);

        int deleted = memberMapper.delete(queryWrapper);
        if (deleted == 0) {
            throw new BusinessException("成员不存在或已被移除");
        }

        log.info("知识库成员移除成功：kbId={}, memberType={}, memberId={}", kbId, memberType, memberId);
    }

    /**
     * 更新成员权限
     *
     * @param kbId       知识库ID
     * @param memberType 成员类型
     * @param memberId   成员ID
     * @param request    更新请求
     * @param operatorId 操作人ID
     * @return 更新后的成员信息
     */
    @Transactional
    public KbMemberVO updateMemberPermission(Long kbId, String memberType, Long memberId,
                                              UpdateKbMemberRequest request, Long operatorId) {
        log.info("更新成员权限：kbId={}, memberType={}, memberId={}, newPermission={}",
                kbId, memberType, memberId, request.getPermissionType());

        // 1. 权限检查：仅owner可操作
        KnowledgeBaseEntity kb = knowledgeBaseMapper.selectById(kbId);
        if (kb == null) {
            throw new BusinessException("知识库不存在");
        }

        if (!kb.getOwnerId().equals(operatorId)) {
            throw new ForbiddenException("仅知识库owner可管理成员");
        }

        // 2. 不能修改owner权限
        if ("user".equals(memberType) && memberId.equals(kb.getOwnerId())) {
            throw new BusinessException("不能修改owner权限");
        }

        // 3. 查找成员记录
        LambdaQueryWrapper<MemberEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MemberEntity::getKbId, kbId)
                .eq(MemberEntity::getMemberType, memberType)
                .eq(MemberEntity::getMemberId, memberId);

        MemberEntity member = memberMapper.selectOne(queryWrapper);
        if (member == null) {
            throw new BusinessException("成员不存在");
        }

        // 4. 更新权限
        member.setPermissionType(request.getPermissionType());
        memberMapper.updateById(member);

        log.info("成员权限更新成功：id={}, newPermission={}", member.getId(), request.getPermissionType());

        // 5. 返回更新后的VO
        return buildMemberVO(member);
    }

    /**
     * 查询知识库所有成员
     *
     * @param kbId   知识库ID
     * @param userId 请求用户ID（用于权限验证）
     * @return 成员列表
     */
    public List<KbMemberVO> listMembers(Long kbId, Long userId) {
        log.debug("查询知识库成员：kbId={}, userId={}", kbId, userId);

        // 1. 验证用户有权限查看成员列表（至少有read权限）
        String userPermission = getUserPermissionInKb(kbId, userId);
        if (userPermission == null) {
            throw new ForbiddenException("无权限查看该知识库成员");
        }

        // 2. 查询所有成员
        LambdaQueryWrapper<MemberEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MemberEntity::getKbId, kbId)
                .orderByDesc(MemberEntity::getGrantedAt);

        List<MemberEntity> members = memberMapper.selectList(queryWrapper);

        // 3. 添加owner记录（owner不在kb_member表中）
        KnowledgeBaseEntity kb = knowledgeBaseMapper.selectById(kbId);
        List<KbMemberVO> result = new ArrayList<>();

        // 添加owner
        if (kb != null && kb.getOwnerId() != null) {
            UserEntity owner = userMapper.selectById(kb.getOwnerId());
            if (owner != null) {
                result.add(KbMemberVO.builder()
                        .memberId(kb.getOwnerId())
                        .memberType("user")
                        .memberName(owner.getUsername())
                        .permissionType("owner")
                        .grantedAt(kb.getCreatedAt())
                        .build());
            }
        }

        // 4. 转换成员列表
        for (MemberEntity member : members) {
            result.add(buildMemberVO(member));
        }

        return result;
    }

    /**
     * 查询用户在知识库中的权限
     *
     * @param kbId   知识库ID
     * @param userId 用户ID
     * @return 权限类型（owner/manage/write/read/null）
     */
    public String getUserPermissionInKb(Long kbId, Long userId) {
        // 1. 检查是否owner
        KnowledgeBaseEntity kb = knowledgeBaseMapper.selectById(kbId);
        if (kb != null && kb.getOwnerId().equals(userId)) {
            return "owner";
        }

        // 2. 检查直接用户授权
        LambdaQueryWrapper<MemberEntity> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(MemberEntity::getKbId, kbId)
                .eq(MemberEntity::getMemberType, "user")
                .eq(MemberEntity::getMemberId, userId);

        MemberEntity userMember = memberMapper.selectOne(userQuery);
        if (userMember != null) {
            return userMember.getPermissionType();
        }

        // 3. 检查部门授权
        UserEntity user = userMapper.selectById(userId);
        if (user != null && user.getDepartmentId() != null) {
            LambdaQueryWrapper<MemberEntity> deptQuery = new LambdaQueryWrapper<>();
            deptQuery.eq(MemberEntity::getKbId, kbId)
                    .eq(MemberEntity::getMemberType, "dept")
                    .eq(MemberEntity::getMemberId, user.getDepartmentId());

            MemberEntity deptMember = memberMapper.selectOne(deptQuery);
            if (deptMember != null) {
                return deptMember.getPermissionType();
            }
        }

        // 4. 无权限
        return null;
    }

    /**
     * 构建MemberVO
     */
    private KbMemberVO buildMemberVO(MemberEntity member) {
        String memberName = getMemberName(member.getMemberType(), member.getMemberId());
        String grantedByName = "Unknown";

        if (member.getGrantedBy() != null) {
            UserEntity grantedByUser = userMapper.selectById(member.getGrantedBy());
            if (grantedByUser != null) {
                grantedByName = grantedByUser.getUsername();
            }
        }

        KbMemberVO vo = KbMemberVO.builder()
                .id(member.getId())
                .memberId(member.getMemberId())
                .memberType(member.getMemberType())
                .memberName(memberName)
                .permissionType(member.getPermissionType())
                .grantedBy(member.getGrantedBy())
                .grantedByName(grantedByName)
                .grantedAt(member.getGrantedAt())
                .build();

        // 如果是部门，统计成员数
        if ("dept".equals(member.getMemberType())) {
            Long count = userMapper.selectCount(
                    new LambdaQueryWrapper<UserEntity>()
                            .eq(UserEntity::getDepartmentId, member.getMemberId())
                            .eq(UserEntity::getStatus, "active")
            );
            vo.setDepartmentMemberCount(count.intValue());
        }

        return vo;
    }

    /**
     * 验证成员并获取成员名称
     */
    private String validateAndGetMemberName(String memberType, Long memberId, Long ownerId) {
        if ("user".equals(memberType)) {
            UserEntity user = userMapper.selectById(memberId);
            if (user == null) {
                throw new BusinessException("用户不存在");
            }

            if (memberId.equals(ownerId)) {
                throw new BusinessException("owner已拥有最高权限，无需重复添加");
            }

            return user.getUsername();

        } else if ("dept".equals(memberType)) {
            DepartmentEntity dept = departmentMapper.selectById(memberId);
            if (dept == null) {
                throw new BusinessException("部门不存在");
            }

            return dept.getName();

        } else {
            throw new BusinessException("无效的成员类型");
        }
    }

    /**
     * 获取成员名称
     */
    private String getMemberName(String memberType, Long memberId) {
        if ("user".equals(memberType)) {
            UserEntity user = userMapper.selectById(memberId);
            return user != null ? user.getUsername() : "Unknown User";
        } else if ("dept".equals(memberType)) {
            DepartmentEntity dept = departmentMapper.selectById(memberId);
            return dept != null ? dept.getName() : "Unknown Department";
        }
        return "Unknown";
    }
}
